<?php
namespace aop\core;

trait MethodClosureCreationTrait {

    private $_method_closure_binding_map = [];

    private function _hasMethodClosure($abstract, $methodName) {
        $methodClosureKey = $this->_createMethodClosureKey($abstract, $methodName);
        if ($methodClosureKey && isset($this->_method_closure_binding_map[$methodClosureKey])) {
            return $this->_method_closure_binding_map[$methodClosureKey];
        } else {
            return NULL;
        }
    }

    private function _saveMethodClosure($abstract, $methodName, $closure) {
        $methodClosureKey = $this->_createMethodClosureKey($abstract, $methodName);
        if ($methodClosureKey) {
            $this->_method_closure_binding_map[$methodClosureKey] = $closure;
        }
    }

    private function _createMethodClosureKey($abstract, $methodName) {
        return $abstract ? ($abstract . '::' . $methodName) : '';
    }

    private function _createClosureWithoutDocument($abstract, $methodName) {
        $closure = function($instance, array $args) use ($methodName) {
            $methodReflection = new \ReflectionMethod($instance, $methodName);
            $methodReflection->setAccessible(TRUE);
            return $methodReflection->invokeArgs($instance, $args);
        };
        $this->_saveMethodClosure($abstract, $methodName, $closure);
        return $closure;
    }
}